package com.antaohua.platfrom.framework.base.dao;

import java.lang.reflect.ParameterizedType;

import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaQuery;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;

import com.antaohua.platfrom.framework.base.exception.QureyEntityException;
import com.antaohua.platfrom.framework.base.interfase.DeleteStateInterfase;
import com.antaohua.platfrom.framework.base.model.UUIDIdentityModel;
import com.antaohua.platfrom.framework.base.utils.Condition;
import com.antaohua.platfrom.framework.base.utils.PageUtil;
import com.google.common.collect.Maps;

//@Deprecated
public abstract class BaseHibernateDao<E extends UUIDIdentityModel> {

	private static Log log = LogFactory.getLog(BaseHibernateDao.class);

	@Autowired
	private SessionFactory sessionFactory;
	
	private final Class<E> persistentClass;
	
	@SuppressWarnings("unchecked")
    public BaseHibernateDao(){
        this.persistentClass = (Class<E>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
	
	
	protected Class<E> getEntityClass(){
		return persistentClass;
	}

	public final Session getSession() {
		Session session = null;
		try {
			session = this.sessionFactory.getCurrentSession();
		} catch (HibernateException e) {
			log.error("Spring未打开Sesson 查看Service 中@Transactional 是否正确！");
			throw new NullPointerException("Spring未打开Sesson 查看Service 中@Transactional 是否正确！");
		}
		return session;
	}

	@SuppressWarnings("deprecation")
	public Criteria getCriteria(){
		return getSession().createCriteria(persistentClass);
	}
	
	public Query<?> getQuery(String queryString) {
		return getSession().createQuery(queryString);
	}

	public <T> Query<T> getQuery(String queryString, Class<T> resultType) {
		return getSession().createQuery(queryString, resultType);
	}

	
	public Query<E> getQuery(CriteriaQuery<E> criteriaQuery) {
		return getSession().createQuery(criteriaQuery);
	}
	
	

	
	
	
	
	
	
	
	public E save(E entity){
		entity = BaseHibernateManager.createEventAutoData(entity);
		getSession().save(entity); 
		return entity;
	}

	public List<E> save(List<E> entitys){
		for (E entity : entitys) {
			save(entity);
		}
		return entitys;
	}
	
	

	public E update(E entity){
		entity = BaseHibernateManager.updateEventAutoData(entity);
		getSession().update(entity);
		return entity;
	}
	
	public List<E> update(List<E> entitys){
		for (E entity : entitys) {
			update(entity);
		}
		return entitys;
	}

	public void delete(E entity){
		if (BaseHibernateManager.isDeleteState(entity)) {
			entity = BaseHibernateManager.deleteEventAutoData(entity);
			getSession().update(entity);

		} else {
			getSession().delete(entity);
		}
	}
	
	
	

	public Integer deleteById(String id){
		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			StringBuffer hql = new StringBuffer("UPDATE ").append(getEntityClass().getSimpleName())
					.append(" entity ").append(" SET ").append(" entity.")
					.append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
					.append(DeleteStateInterfase.DELETE_FALSE).append(" WHERE entity.ID = :id");
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			qurey.setParameter("id", id);
			return qurey.executeUpdate();
		} else {
			StringBuffer hql = new StringBuffer("Delete FROM ").append(getEntityClass().getSimpleName())
					.append(" WHERE ID = :id");
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			qurey.setParameter("id", id);
			return qurey.executeUpdate();
		}
	}

	public Integer deleteByIds(List<String> ids){
		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			StringBuffer hql = new StringBuffer("UPDATE ").append(getEntityClass().getSimpleName())
					.append(" entity ").append(" SET ").append(" entity.")
					.append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
					.append(DeleteStateInterfase.DELETE_TRUE).append(" WHERE entity.ID in (:ids)");
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			qurey.setParameterList("ids", ids);
			return qurey.executeUpdate();
		} else {
			StringBuffer hql = new StringBuffer("Delete FROM ").append(getEntityClass().getSimpleName())
					.append(" WHERE ID in (:ids)");
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			qurey.setParameterList("ids", ids);
			return qurey.executeUpdate();
		}
	}

	public Integer deleteByProperty(Map<String, Object> propertys) {
		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			StringBuffer hql = new StringBuffer("UPDATE ").append(getEntityClass().getSimpleName())
					.append(" entity ").append(" SET ").append(" entity.")
					.append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
					.append(DeleteStateInterfase.DELETE_TRUE).append(" WHERE 1=1 ");
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if (property.getValue() != null) {
					hql.append(" AND ").append(property.getKey()).append(" =:").append(property.getKey());
				} else {
					hql.append(" AND ").append(property.getKey()).append(" IS NULL ");
				}

			}
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if (property.getValue() != null) {
					qurey.setParameter(property.getKey(), property.getValue());
				}
			}
			return qurey.executeUpdate();
		} else {
			StringBuffer hql = new StringBuffer("Delete FROM ").append(getEntityClass().getSimpleName())
					.append(" WHERE 1=1 ");
			for (String propertyName : propertys.keySet()) {
				hql.append(" AND ").append(propertyName).append(" =:").append(propertyName);
			}
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if (property.getValue() != null) {
					qurey.setParameter(property.getKey(), property.getValue());
				}
			}
			return qurey.executeUpdate();
		}
	}

	public Integer deleteByProperty(String propertyName, Object propertyValue){
		Map<String, Object> property = Maps.newHashMap();
		property.put(propertyName,propertyValue);
		return deleteByProperty(property);
	}

	@SuppressWarnings("unchecked")
	public E findById(String id) throws QureyEntityException {
		Criteria criteria = getCriteria();
		criteria.add(Condition.eq.getHibernateCriterion("id", id));
		criteria.add(Condition.eq.getHibernateCriterion(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME, DeleteStateInterfase.DELETE_FALSE));
		return (E)criteria.uniqueResult();
	}
 
	public List<E> findByIds(List<String> ids) throws QureyEntityException {
		try {
			StringBuffer hql = new StringBuffer("FROM ");
			hql.append(getEntityClass().getSimpleName());
			if (BaseHibernateManager.isDeleteState(persistentClass)) {
				hql.append(" WHERE ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
						.append(DeleteStateInterfase.DELETE_FALSE);
			}
			Query<E> query = getQuery(hql.toString(), getEntityClass());
			return query.list();
		} catch (Exception e) {
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
	}

	public PageUtil<E> findAll(PageUtil<E> page) throws QureyEntityException {

		String hql = "FROM " + getEntityClass().getSimpleName();
		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			hql += " Where " + DeleteStateInterfase.DELTET_ATTRIBUTE_NAME + " = " + DeleteStateInterfase.DELETE_FALSE;
		}
		Query<E> qurey = getQuery(hql, getEntityClass());
		qurey.setFirstResult(page.getFirstNumber());
		qurey.setMaxResults(page.getLimit().intValue());
		List<E> list = null;
		try {
			list = qurey.list();
		} catch (Exception e) {
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
		page.getRoot().addAll(list);
		page.setTotal(countAll());
		return page;
	}

	public List<E> findAll() throws QureyEntityException {
		String hql = "FROM " + getEntityClass().getSimpleName();

		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			hql += " Where " + DeleteStateInterfase.DELTET_ATTRIBUTE_NAME + " = " + DeleteStateInterfase.DELETE_FALSE;
		}
		Query<E> qurey = getQuery(hql, getEntityClass());
		try {
			return qurey.list();
		} catch (Exception e) {
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
	}

	public List<E> findByProperty(String propertyName, Object value) throws QureyEntityException {
		try {
			StringBuffer hql = new StringBuffer("FROM ");
			hql.append(getEntityClass().getSimpleName()).append(" where 1=1");
			hql.append(" and ");

			if (value == null) {
				hql.append(propertyName).append(" is null");
			} else {
				hql.append(propertyName).append(" = ").append(":").append(propertyName);
			}

			if (BaseHibernateManager.isDeleteState(persistentClass)) {
				hql.append(" and ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
						.append(DeleteStateInterfase.DELETE_FALSE);
			}
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			if (value != null) {
				qurey.setParameter(propertyName, value);
			}
			return qurey.list();
		} catch (Exception e) {
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
	}

	public List<E> findByProperty(Map<String, Object> propertys) throws QureyEntityException {
		try {
			if ((propertys == null) || (propertys.size() == 0)) {
				return findAll();
			}
			StringBuffer hql = new StringBuffer("FROM ");
			hql.append(getEntityClass().getSimpleName()).append(" AS P ").append(" WHERE 1=1");
			if (BaseHibernateManager.isDeleteState(persistentClass)) {
				hql.append(" AND ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
						.append(DeleteStateInterfase.DELETE_FALSE);
			}
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if ((property.getKey() != null) && (!((String) property.getKey()).trim().equals(""))) {
					hql.append(" AND ");

					if (property.getValue() == null) {
						hql.append("P.").append(property.getKey()).append(" IS NULL ");
					} else {
						hql.append("P.").append(property.getKey()).append("=").append(":").append(property.getKey());
					}
				}
			}
			Query<E> qurey = getQuery(hql.toString(), getEntityClass());
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if (property.getValue() != null) {
					qurey.setParameter(property.getKey(), property.getValue());
				}
			}
			return qurey.list();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
	}

	public Long countByProperty(String propertyName, Object value) throws QureyEntityException {
		try {
			StringBuffer hql = new StringBuffer("select count(*) FROM ");
			hql.append(getEntityClass().getSimpleName()).append(" where 1=1 ");
			if (value == null) {
				hql.append(" and ").append(propertyName).append(" is null ");
			} else {
				hql.append(" and ").append(propertyName).append(" = ").append(":").append(propertyName);
			}
			if (BaseHibernateManager.isDeleteState(persistentClass)) {
				hql.append(" and ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
						.append(DeleteStateInterfase.DELETE_FALSE);
			}
			System.out.println(hql);
			Query<Long> qurey = getQuery(hql.toString(), Long.class);
			qurey.setParameter(propertyName, value);
			return qurey.uniqueResult();
		} catch (Exception e) {
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
	}

	public Long countByProperty(Map<String, Object> propertys) throws QureyEntityException {
		try {
			StringBuffer hql = new StringBuffer("select count(*) FROM ");
			hql.append(getEntityClass().getSimpleName()).append(" where 1=1 ");
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if (property.getValue() == null) {
					hql.append(" and ").append(property.getKey()).append(" is null ");
				} else {
					hql.append(" and ").append(property.getKey()).append(" = ").append(":").append(property.getKey());
				}
			}

			if (BaseHibernateManager.isDeleteState(persistentClass)) {
				hql.append(" and ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
						.append(DeleteStateInterfase.DELETE_FALSE);
			}
			Query<Long> qurey = getQuery(hql.toString(), Long.class);
			for (Map.Entry<String, Object> property : propertys.entrySet()) {
				if (property.getValue() != null) {
					qurey.setParameter(property.getKey(), property.getValue());
				}
			}
			return qurey.uniqueResult();
		} catch (Exception e) {
			log.error(e);
			throw new QureyEntityException(e.getMessage());
		}
	}

	public Long countAll() throws QureyEntityException {

		StringBuffer hql = new StringBuffer("select count(*) FROM ");
		hql.append(getEntityClass().getSimpleName()).append(" where 1=1");

		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			hql.append(" and ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
					.append(DeleteStateInterfase.DELETE_FALSE);
		}
		Query<Long> qurey = getQuery(hql.toString(), Long.class);

		return qurey.uniqueResult();
	}

	public Boolean isExistence(String propertyName, Object value) throws QureyEntityException {
		StringBuffer hql = new StringBuffer("select count(*) FROM ");
		hql.append(getEntityClass().getSimpleName()).append(" where 1=1 ");
		if (value == null) {
			hql.append(propertyName).append(" is null ");
		} else {
			hql.append(propertyName).append("=").append(":").append(value);
		}
		if (BaseHibernateManager.isDeleteState(persistentClass)) {
			hql.append(" and ").append(DeleteStateInterfase.DELTET_ATTRIBUTE_NAME).append(" = ")
					.append(DeleteStateInterfase.DELETE_FALSE);
		}
		Query<E> qurey = getQuery(hql.toString(), getEntityClass());
		if (Integer.valueOf(qurey.uniqueResult().toString()) > 0) {
			return Boolean.valueOf(false);
		} else {
			return Boolean.valueOf(true);
		}
	}

	

}
